home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 August
/
CICA - The Ultimate Collection of Shareware for Windows (Disc 2) (August 1995).iso
/
disc2
/
demo
/
pwrtcp11.exe
/
DGC.C_
/
DGC.bin
Wrap
Text File
|
1995-02-17
|
21KB
|
712 lines
#pragma warning(disable : 4001) /* Allow // comments */
//***************************************************************************
//
// Module: dgc.c
//
// Tab setting: 4
//
//***************************************************************************
//
// Written by Dart Communication Application Programming Group.
// Copyright (c) 1994 Dart Communications. All Rights Reserved.
//
// Purpose: Provides access to functions in UDP interface
// DLL via dialog box.
//
// Author: Roger Lathrop
//
// History: 12/94 - First version.
//
//***************************************************************************
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
// UDP Include files. Common brings in windows.h for us.
#include "..\..\include\common.h"
#include "..\..\include\powertcp.h"
// Our resource file header.
#include "dgc.hh"
/****************************************************************************
* Static variables for module.
****************************************************************************/
static HICON hOurIcon; // Handle to our application icon.
// Proc instance address for callback functions.
static CONNECTUDPEVENT lpfnConnectUdpEvent;
static EXCEPTIONUDPEVENT lpfnExceptionUdpEvent;
static RECVUDPEVENT lpfnRecvUdpEvent;
static SENDEVENT lpfnSendEvent;
#define PORT_1 0 // Port controlled by left side of dialog box
#define PORT_2 1 // Port controlled by right side of dialog box
// Macro to get control id from Port and left hand side control id.
// Control id's on right are left id + 100.
#define PORTCTLID(Port,ctlid) ((WORD)((Port==PORT_1) ? (ctlid) : (ctlid+100)))
static HWND hOurWnd; // Our window handle
static HPOWERTCP hMyPowerTcp[2]; // Handles to PowerTCP session.
/****************************************************************************
* Routines for fetching parameters from edit controls.
****************************************************************************/
//---------------------------------------------------------------------------
// Name.......: GetStringParam
// Purpose....: Get a string from an edit control.
//
// Parameters.: CtlId - WORD Control id of edit control
// Required - BOOL Parameter is required.
//
// Returns....: Malloced pointer to string, or NULL if malloc fails
//---------------------------------------------------------------------------
static char * GetStringParam(WORD CtlId,BOOL Required)
{ char *p;
WORD len;
// Get length of string in edit control. If length is 0,
// and the parameter is required, then ding the speaker,
// set focus to control, and put message in status bar.
len = (WORD)SendDlgItemMessage(hOurWnd,CtlId,WM_GETTEXTLENGTH,0,0);
if(len == 0 && Required)
{
MessageBeep(0);
SetFocus(GetDlgItem(hOurWnd,CtlId));
return NULL;
}
// Allocate space for string and a NULL byte.
len++;
p = malloc(len);
// Malloc should never fail, unless we have a memory leak,
// but best to check anyway.
if(p)
{ // Extract string from edit control.
SendDlgItemMessage(hOurWnd,CtlId,WM_GETTEXT,len,(LPARAM)(LPSTR)p);
}
return p;
}
//---------------------------------------------------------------------------
// Name.......: FreeStringParam
// Purpose....: Free a string allocated by GetStringParam.
// Checks for NULL string so caller doesn't have to.
//
// Parameters.: s - Char * String from GetStringParam
//
// Returns....: void
//---------------------------------------------------------------------------
static void FreeStringParam(char *s)
{
if(s)
{
free(s);
}
}
//---------------------------------------------------------------------------
// Name.......: GetWordParam
// Purpose....: Get an int from an edit control.
//
// Parameters.: CtlId - WORD Control id of edit control
// pval - LPWORD far pointer to area to receive value.
//
// Returns....: True if numeric value in edit control.
//---------------------------------------------------------------------------
BOOL GetWordParam(WORD CtlId,LPWORD pval)
{ char *p;
char *psave;
// Get text from edit control. Skip leading whitespace, then
// if first character is a digit, convert string to long.
// If not a digit, ding the speaker and set focus to control.
p = GetStringParam(CtlId,TRUE);
psave = p;
if(p)
{
while(isspace(*p))
{
p++;
}
if(isdigit(*p))
{
*pval = (WORD)atoi(p);
free(psave);
return TRUE;
}
else
{
MessageBeep(0);
SetFocus(GetDlgItem(hOurWnd,CtlId));
free(psave);
*pval = 0;
return FALSE;
}
}
return FALSE;
}
//---------------------------------------------------------------------------
// Name.......:ReadIniVal
// Purpose....:Reads one ini value
//---------------------------------------------------------------------------
static void ReadIniVal(char *name,WORD id)
{ static char Value[128];
GetPrivateProfileString("DGC",
name,
"",
Value,
sizeof Value,
"DGC.INI");
SendDlgItemMessage(hOurWnd,id,WM_SETTEXT,0,(LPARAM)(LPCSTR)Value);
}
//---------------------------------------------------------------------------
// Name.......:WriteIniVal
// Purpose....:Writes one ini value
//---------------------------------------------------------------------------
static void WriteIniVal(char *name,WORD id)
{ char *Value;
Value = GetStringParam(id,FALSE);
if(Value)
{
WritePrivateProfileString("DGC",
name,
Value,
"DGC.INI");
FreeStringParam(Value);
}
}
//---------------------------------------------------------------------------
// Name.......:ReadIniFile
// Purpose....:Reads default values from INI file.
//---------------------------------------------------------------------------
static void ReadIniFile(void)
{
ReadIniVal("OEMLICENSE",EDC_LICENSE);
ReadIniVal("DATAG_1",EDC_SND_DATAG_1);
ReadIniVal("DATAG_2",EDC_SND_DATAG_2);
ReadIniVal("ADDR_1",EDC_SND_ADDR_1);
ReadIniVal("ADDR_2",EDC_SND_ADDR_2);
ReadIniVal("REPS_1",EDC_SND_REPS_1);
ReadIniVal("REPS_2",EDC_SND_REPS_2);
ReadIniVal("SND_PORT_1",EDC_SND_PORT_1);
ReadIniVal("SND_PORT_2",EDC_SND_PORT_2);
ReadIniVal("PORT_1",EDC_PORT_1);
ReadIniVal("PORT_2",EDC_PORT_2);
ReadIniVal("SND_PORT_1",EDC_SND_PORT_1);
}
//---------------------------------------------------------------------------
// Name.......:WriteIniFile
// Purpose....:Writes current values to ini file
//---------------------------------------------------------------------------
static void WriteIniFile(void)
{
WriteIniVal("OEMLICENSE",EDC_LICENSE);
WriteIniVal("DATAG_1",EDC_SND_DATAG_1);
WriteIniVal("DATAG_2",EDC_SND_DATAG_2);
WriteIniVal("ADDR_1",EDC_SND_ADDR_1);
WriteIniVal("ADDR_2",EDC_SND_ADDR_2);
WriteIniVal("REPS_1",EDC_SND_REPS_1);
WriteIniVal("REPS_2",EDC_SND_REPS_2);
WriteIniVal("SND_PORT_1",EDC_SND_PORT_1);
WriteIniVal("SND_PORT_2",EDC_SND_PORT_2);
WriteIniVal("PORT_1",EDC_PORT_1);
WriteIniVal("PORT_2",EDC_PORT_2);
WriteIniVal("SND_PORT_1",EDC_SND_PORT_1);
}
//---------------------------------------------------------------------------
// Name.......: ShowState
// Purpose....: Show the state of a port
//
// Parameters.: Port - WORD PORT_1 or PORT_2
//
// Returns....: void
//---------------------------------------------------------------------------
static void ShowState(WORD Port)
{ PT_STATE state;
char *str;
if(hMyPowerTcp[Port])
{
state = StateUdp(hMyPowerTcp[Port]);
switch(state)
{
case PT_INVALID: str = "Invalid State"; break;
case PT_CLOSED: str = "Closed"; break;
case PT_CONNECTING: str = "Connecting"; break;
case PT_CONNECTED: str = "Connected"; break;
case PT_LISTENING: str = "Listening"; break;
case PT_CLOSING: str = "Closing"; break;
default: str = "UNKNOWN state!!!"; break;
}
}
else
{
str = "Closed";
}
SetDlgItemText(hOurWnd,PORTCTLID(Port,STC_STATUS_1),str);
}
/****************************************************************************
* CALLBACK FUNCTIONS. Called asynchronously by DLL as events occur.
****************************************************************************/
//---------------------------------------------------------------------------
// Name.......: ConnectUdpEvent
// Purpose....: Callback function for connect event notification
//
// Parameters.: hSession - HPOWERTCP Session id.
// UserData - DWORD User data supplied to loginhost.
// LocalDotAddr - LPCSTR Local dot address
// LocalPort - WORD Local port id.
// LocalName - LPCSTR Local name.
// MaxByteCnt - WORD Largest datagram.
//
// Returns....: void
//---------------------------------------------------------------------------
void CALLBACK ConnectUdpEvent(HPOWERTCP hSession,
DWORD UserData,
LPCSTR LocalDotAddr,
WORD LocalPort,
LPCSTR LocalName,
WORD MaxByteCnt)
{
if(hMyPowerTcp[LOWORD(UserData)])
{
ShowState((WORD)UserData);
}
}
//---------------------------------------------------------------------------
// Name.......: ExceptionEvent
// Purpose....: Callback function for exception event notification
//
// Parameters.: hSession - HPOWERTCP Session id.
// UserData - DWORD PORT_1 or PORT_2
// Error - PT_EXCEPTION Enumerated exception type.
// ErrorType - LPCSTR Error type description string.
// DataTag - DWORD If not 0, identifies exception packet.
//
// Returns....: void
//---------------------------------------------------------------------------
void CALLBACK ExceptionUdpEvent(HPOWERTCP hSession,
DWORD UserData,
PT_EXCEPTION Error,
LPCSTR ErrorDesc,
DWORD DataTag)
{
SetDlgItemText(hOurWnd,PORTCTLID(UserData,STC_STATUS_1),ErrorDesc);
}
//---------------------------------------------------------------------------
// Name.......: RecvUdpEvent
// Purpose....: Callback function for received data notification
//
// Parameters.: hSession - HPOWERTCP Session id.
// UserData - DWORD User data supplied to ConnectUdp.
// Data - LPVOID Data from remote source
// ByteCnt - size_t byte count for received data
// RemoteDotAddr - LPCSTR source address of datagram
// RemotePort - WORD source port of datagram
//
// Returns....: void
//---------------------------------------------------------------------------
void CALLBACK RecvUdpEvent(HPOWERTCP hSession,
DWORD UserData,
LPVOID Data,
size_t ByteCnt,
LPCSTR RemoteDotAddr,
WORD RemotePort)
{ WORD sent;
char *p;
if((Data==NULL) && (ByteCnt == 0))
{ // Special case, indicates port has closed.
ShowState((WORD)UserData);
return;
}
GetWordParam(PORTCTLID(UserData,EDC_RCV_TOTAL_1),&sent);
sent += (WORD)ByteCnt;
SetDlgItemInt(hOurWnd,PORTCTLID(UserData,EDC_RCV_TOTAL_1),sent,FALSE);
SetDlgItemInt(hOurWnd,PORTCTLID(UserData,EDC_RCV_PORT_1),RemotePort,FALSE);
SetDlgItemText(hOurWnd,PORTCTLID(UserData,EDC_RCV_ADDR_1),RemoteDotAddr);
// Duplicate the data so we can NULL terminate it.
p = malloc(ByteCnt + 1);
if(p)
{
_fmemcpy(p,Data,ByteCnt);
p[ByteCnt] = '\0';
SetDlgItemText(hOurWnd,PORTCTLID(UserData,EDC_RCV_DATAG_1),p);
free(p);
}
}
//---------------------------------------------------------------------------
// Name.......: SendEvent
// Purpose....: Callback function for send event notification
//
// Parameters.: hSession - HPOWERTCP Session id.
// UserData - DWORD PORT_1 or PORT_2
// Tag - DWORD Size of data packed, see ActionSend
//
// Returns....: void
//---------------------------------------------------------------------------
void CALLBACK SendEvent(HPOWERTCP hSession,DWORD UserData,DWORD Tag)
{ WORD sent;
// Get edit control value, add Tag to it, reset edit control value.
GetWordParam(PORTCTLID(UserData,EDC_SND_TOTAL_B_1),&sent);
sent += (WORD)Tag;
SetDlgItemInt(hOurWnd,PORTCTLID(UserData,EDC_SND_TOTAL_B_1),sent,FALSE);
}
/****************************************************************************
* ActionXxx Functions. Handle user actions, dispatched from MainWndProc.
****************************************************************************/
//---------------------------------------------------------------------------
// Name.......: ActionSend
// Purpose....: Send data
//---------------------------------------------------------------------------
static void ActionSend(WORD Port)
{ char *Data;
char *Host;
WORD RemotePort;
WORD Reps;
WORD len;
WORD sent;
// Get the string to send, host address, port number, and
// repeat count.
Data = GetStringParam(PORTCTLID(Port,EDC_SND_DATAG_1),TRUE);
if(!Data)
{
return;
}
Host = GetStringParam(PORTCTLID(Port,EDC_SND_ADDR_1),FALSE);
if(!Host)
{
FreeStringParam(Data);
return;
}
GetWordParam(PORTCTLID(Port,EDC_SND_PORT_1),&RemotePort);
GetWordParam(PORTCTLID(Port,EDC_SND_REPS_1),&Reps);
len = (WORD)strlen(Data);
// Get current total from control
GetWordParam(PORTCTLID(Port,EDC_SND_TOTAL_A_1),&sent);
while(Reps--)
{ // Send packet Reps times. len is used as DataTag
// so that RecvUdpEvent can update totals.
SendUdp(hMyPowerTcp[Port],
Host,
RemotePort,
Data,
len,
len);
// Update total sent.
sent += len;
SetDlgItemInt(hOurWnd,PORTCTLID(Port,EDC_SND_TOTAL_A_1),
sent,FALSE);
}
FreeStringParam(Data);
FreeStringParam(Host);
}
//---------------------------------------------------------------------------
// Name.......: ActionOpen
// Purpose....: Handle BTN_OPEN_X command.
//---------------------------------------------------------------------------
static void ActionOpen(WORD Port)
{ WORD pt;
BOOL res;
char *license;
res = GetWordParam(PORTCTLID(Port,EDC_PORT_1),&pt);
if(!res)
{
return;
}
license = GetStringParam(EDC_LICENSE,FALSE);
hMyPowerTcp[Port] = ConnectUdp( Port, // User data identifies port.
license,
PT_SHOW, // show PowerTCP icon
NULL,
pt,
lpfnConnectUdpEvent,
lpfnRecvUdpEvent,
lpfnSendEvent,
lpfnExceptionUdpEvent);
ShowState(Port);
if(!hMyPowerTcp[Port])
{
MessageBox(hOurWnd,"ConnectUdp Failed","UDP Error",MB_OK);
}
}
//---------------------------------------------------------------------------
// Name.......: ActionClose
// Purpose....: Handle BTN_CLOSE_X command.
//---------------------------------------------------------------------------
static void ActionClose(WORD Port)
{
if(hMyPowerTcp[Port])
{
CloseUdp(hMyPowerTcp[Port],FALSE);
hMyPowerTcp[Port] = NULL;
ShowState((WORD)Port);
}
}
//---------------------------------------------------------------------------
// Name.......: ActionClear
// Purpose....: Handle BTN_CLEAR command
//---------------------------------------------------------------------------
static void ActionClear(void)
{
SetDlgItemInt(hOurWnd,EDC_SND_TOTAL_A_1,0,FALSE);
SetDlgItemInt(hOurWnd,EDC_SND_TOTAL_B_1,0,FALSE);
SetDlgItemInt(hOurWnd,EDC_SND_TOTAL_A_2,0,FALSE);
SetDlgItemInt(hOurWnd,EDC_SND_TOTAL_B_2,0,FALSE);
SetDlgItemInt(hOurWnd,EDC_RCV_TOTAL_1,0,FALSE);
SetDlgItemInt(hOurWnd,EDC_RCV_TOTAL_2,0,FALSE);
SetDlgItemText(hOurWnd,EDC_RCV_DATAG_2,"");
SetDlgItemText(hOurWnd,EDC_RCV_ADDR_2,"");
SetDlgItemText(hOurWnd,EDC_RCV_PORT_2,"");
SetDlgItemText(hOurWnd,EDC_RCV_DATAG_1,"");
SetDlgItemText(hOurWnd,EDC_RCV_ADDR_1,"");
SetDlgItemText(hOurWnd,EDC_RCV_PORT_1,"");
}
//---------------------------------------------------------------------------
// Name.......: ActionIDOK
// Purpose....: Handle IDOK (User hits enter)
//---------------------------------------------------------------------------
static void ActionIDOK(void)
{ int id;
id = GetDlgCtrlID(GetFocus());
switch(id)
{
case EDC_SND_ADDR_1:
case EDC_SND_PORT_1:
case EDC_SND_REPS_1:
case EDC_SND_TOTAL_A_1:
case EDC_SND_TOTAL_B_1:
case EDC_SND_DATAG_1: ActionSend(PORT_1); break;
case EDC_SND_ADDR_2:
case EDC_SND_PORT_2:
case EDC_SND_REPS_2:
case EDC_SND_TOTAL_A_2:
case EDC_SND_TOTAL_B_2:
case EDC_SND_DATAG_2: ActionSend(PORT_2); break;
default: MessageBeep(0);
}
}
//---------------------------------------------------------------------------
// Name.......:MainWndProc
// Purpose....:Main windows procedure for UDP Test Program.
//---------------------------------------------------------------------------
static DLGPROC lpfnMainWndProc;
BOOL CALLBACK MainWndProc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
HDC hDc;
PAINTSTRUCT ps;
switch(wMessage)
{
case WM_INITDIALOG :
hOurWnd = hWnd;
ReadIniFile();
ActionClear(); // initialize
return TRUE;
case WM_COMMAND :
// Dispatch a button click.
switch(wParam)
{
case BTN_EXIT:
if(hMyPowerTcp[PORT_1])
{
CloseUdp(hMyPowerTcp[PORT_1],TRUE);
}
if(hMyPowerTcp[PORT_2])
{
CloseUdp(hMyPowerTcp[PORT_2],TRUE);
}
WriteIniFile();
PostQuitMessage(0);
break;
case IDOK: ActionIDOK(); break;
case BTN_OPEN_1: ActionOpen(PORT_1); break;
case BTN_OPEN_2: ActionOpen(PORT_2); break;
case BTN_CLOSE_1: ActionClose(PORT_1); break;
case BTN_CLOSE_2: ActionClose(PORT_2); break;
case BTN_CLEAR: ActionClear(); break;
}
break;
case WM_SYSCOMMAND :
switch(wParam & 0xFFF0)
{
case SC_CLOSE :
if(hMyPowerTcp[PORT_1])
{
CloseUdp(hMyPowerTcp[PORT_1],TRUE);
}
if(hMyPowerTcp[PORT_2])
{
CloseUdp(hMyPowerTcp[PORT_2],TRUE);
}
WriteIniFile();
PostQuitMessage(0);
return TRUE;
}
break;
case WM_PAINT:
// Since we don't register a class, we draw our own
// icon when we are minimized.
if(IsIconic(hWnd))
{
hDc = BeginPaint(hWnd,&ps);
DrawIcon(hDc,0,0,hOurIcon);
EndPaint(hWnd,&ps);
}
break;
case WM_ERASEBKGND:
// The icon contains some transparent pixels. If we
// just ignore the erase background message, then
// DefDlgProc paints the background white. If we
// swallow the message, then garbage is left in the
// transparent areas when another window hides the
// icon and is then moved. Microsoft solved this problem
// years ago. The solution is in DefWindowProc, case
// WM_ICONERASEBKGND. So let them do the work!
if(IsIconic(hWnd))
{
return (BOOL)DefWindowProc(hWnd,WM_ICONERASEBKGND,wParam,lParam);
}
break;
case WM_DESTROY :
PostQuitMessage(0);
break;
default :
return FALSE;
}
return FALSE;
}
//---------------------------------------------------------------------------
// Name.......:WinMain
// Purpose....:Create application dialog and dispatch messages.
//---------------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, // Application Instance Handle
HINSTANCE hPrevInstance, // Previous Instance Handle
LPSTR lpszCmdLine, // Pointer to Command Line
int nCmdShow) // Show Window Option
{
static char szAppName[] = "DGC";
HINSTANCE hInst;
MSG msg;
HWND hWndMain;
hInst = hInstance;
hOurIcon = LoadIcon(hInst,szAppName);
lpfnMainWndProc = (DLGPROC)MakeProcInstance((FARPROC)MainWndProc,hInst);
lpfnConnectUdpEvent = (CONNECTUDPEVENT)MakeProcInstance((FARPROC)ConnectUdpEvent,
hInst);
lpfnExceptionUdpEvent = (EXCEPTIONUDPEVENT)MakeProcInstance((FARPROC)ExceptionUdpEvent,hInst);
lpfnRecvUdpEvent = (RECVUDPEVENT)MakeProcInstance((FARPROC)RecvUdpEvent,hInst);
lpfnSendEvent = (SENDEVENT)MakeProcInstance((FARPROC)SendEvent,hInst);
if(!(hWndMain = CreateDialog(hInst,
szAppName,
NULL,
lpfnMainWndProc)))
{
MessageBox(NULL, "Unable to display main dialog", "System Error", MB_OK);
return FALSE;
}
ShowWindow(hWndMain, nCmdShow);
UpdateWindow(hWndMain);
while(GetMessage(&msg, NULL, 0, 0))
if(!IsDialogMessage(hWndMain, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
FreeProcInstance((FARPROC)lpfnMainWndProc);
FreeProcInstance((FARPROC)lpfnConnectUdpEvent);
FreeProcInstance((FARPROC)lpfnExceptionUdpEvent);
FreeProcInstance((FARPROC)lpfnRecvUdpEvent);
FreeProcInstance((FARPROC)lpfnSendEvent);
return msg.wParam;
}